/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.mzk.oai.metadataRepository.harvest;

import cz.mzk.oai.metadataRepository.tools.CannotReadDirectoryException;
import cz.mzk.oai.metadataRepository.Tools;
import cz.mzk.oai.metadataRepository.metadata.DateStamp;
import cz.mzk.oai.metadataRepository.repository.MetadataBase;
import cz.mzk.oai.metadataRepository.repository.Repository;
import cz.mzk.oai.metadataRepository.tools.FileTools;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
import org.dom4j.Document;
import org.dom4j.DocumentException;

/**
 * This class performs the 'harvesting' of directory. It loads the metadata in directory and
 * @author Martin Rehanek, Martin.Rehanek@gmail.com
 */
public class DirectoryHarvester implements MarcHarvester {

    private File sourceDir;
    private Repository repository;
    private Handler logHandler;
  
    /**
     * @param sourceDirName name of directory containing metadata (in marc21)
     * @param repository
     * @param logFileName full name of log file
     * @throws IOException if the log file could not be intitialized
     */
    public DirectoryHarvester(String sourceDirName, Repository repository, String logFileName) throws IOException {
        sourceDir = new File(sourceDirName);
        this.repository = repository;
        if (!sourceDir.exists()) {
            throw new IllegalArgumentException("directory '" + sourceDir + "' does not exist");
        }
        Logger logger = Logger.getLogger(DirectoryHarvester.class.getName());
        logHandler = new FileHandler(logFileName, true);
        logHandler.setFormatter(new SimpleFormatter());
        logger.addHandler(logHandler);
    }

    public void harvestAndUpdate(DateStamp from, DateStamp until, boolean thorough) {
        throw new UnsupportedOperationException();
    }

    /**
     * Harvests all directory.
     * Note that when harvesting directory the datestamp is not derived from file information but is set to moment of harvesting.
     * It means that if there is already present an item with the id, it is replaced.
     * from and until are not taken into consideration
     */
    public void harvestAndReplace(DateStamp from, DateStamp until, boolean thorough) {
        //TODO: implementovat omezeni s from until
        List<String> fileNames = null;
        try {
            fileNames = FileTools.readFilenames(sourceDir);
        } catch (CannotReadDirectoryException ex) {
            Logger.getLogger(DirectoryHarvester.class.getName()).log(Level.SEVERE, null, ex);
        }
        System.out.println("Number of files in " + sourceDir.getAbsolutePath() + ": " + fileNames.size());

        int fileCounter = 0;
        for (String fileName : fileNames) {
            fileCounter++;
            if (fileCounter > 0)//64000)//3509)//TODO: remove after tested
            {
                File file = new File(sourceDir + File.separator + fileName);
                if (file.isFile()) { //adresare nebereme
                    try {
                        if (fileCounter % 1000 == 0) {//TODO: analyzovat, kdy opravdu volat GC
                            System.out.println("so far harvested " + fileCounter + " files");
                            Runtime r = Runtime.getRuntime();
                            r.gc();
                        }
                        Document doc = FileTools.loadDocument(file);
                        String id = Tools.filenameToId(fileName);
                        DateStamp datestamp = new DateStamp();
                        repository.addToCollection(MetadataBase.MZK03,doc, id, datestamp, thorough,false);
                    } catch (DocumentException ex) {
                        Logger.getLogger(DirectoryHarvester.class.getName()).log(Level.SEVERE, null, ex);
                    } catch (FileNotFoundException ex) {
                        Logger.getLogger(DirectoryHarvester.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
        }
        System.out.println("Harvested " + fileCounter + "files");
    }

    /**
     * This method releases allocated resources. (Files etc.)
     * Should be called after we finish working with the DirectoryHarvester instance
     */
    public void close() {
        logHandler.close();
        repository.close();
    }
}
